#include "GraphReader.h"


GraphReader::GraphReader(IncidenceGraph& g)
	: graph(g)
{
}


GraphReader::~GraphReader()
{
}


bool GraphReader::Read(String fileName)
{
	graph.Clear();

	Ifstream ifs(fileName, Ifstream::in);
	if (ifs.bad()) {
		return false;
	}

	// read graph type
	String graphType;
	ifs >> graphType;

	// read graph
	if (graphType == _T("adjacency_matrix")) {
		return ReadAdjacencyMatrix(ifs);
	}
	else if (graphType == _T("adjacency_list")) {
		return ReadAdjacencyList(ifs);
	}

	graph.Clear();

	return false;
}

bool GraphReader::ReadAdjacencyMatrix(Ifstream& ifs)
{
	// read vertex count
	int vertexCount;
	ifs >> vertexCount;
	
	// read matrix
	String s;
	float weight;
	for (int i = 0; i < vertexCount; i++) {
		for (int j = 0; j < vertexCount; j++) {
			if (ifs.bad()) return false;

			ifs >> s;
			if (s == _T("-")) continue;
			
			weight = lexical_cast<float, String>(s);
			if (weight > -1.0f) {
				graph.AddUndirectedEdge(i, j, weight);
			}
		}
	}

	return true;
}

bool GraphReader::ReadAdjacencyList(Ifstream& ifs)
{
	// read vertex count
	String type;
	ifs >> type;
	bool directed = (type == _T("directed"));

	// read matrix
	int source, target;
	float weight;
	while (ifs.good()) {
		ifs >> source;
		ifs >> target;
		ifs >> weight;
		if (directed)
			graph.AddDirectedEdge(source, target, weight);
		else
			graph.AddUndirectedEdge(source, target, weight);
	}

	return true;
}


template<typename TTo, typename TFrom>
TTo GraphReader::lexical_cast(TFrom const &x) {
  Stringstream os;
  TTo ret;

  os << x;
  os >> ret;

  return ret;  
}
